Filling a Combobox with BranchLabels

level: beginner - intermediate

by Alyce Watson [http://alycesrestaurant.com/]

Home

LB Wire Frame Lib

Stylebits - Listboxes

IExpress

Prompt

Icons

Screen Capture

Eddie's Lessons

Combobox

Scrolling Texteditor

Nested If/Then

Sprite Byte

Eddie

Moving Listbox Items

Newsletter help

Submissions

Index


BranchLabels in a Combobox

In version 4, Eddie has a new combobox that lists the branchlabels, subs and functions. See Eddie v4. When the user selects a branchlabel name from the list, the texteditor scrolls to put that line at the top. This is a very useful feature!

When do the branchlabels get into the combobox? It makes sense to fill the combobox whenever a file is opened.

    'code for file open routine
    gosub [fillBranch]

That's great, but we'd like to keep the combobox current with a list of all branchlabels. If the user adds a new branchlabel, sub or function, it should be included in the list.

Here's one way to do it. Eddie already uses a timer to see if the user has scrolled the texteditor. If the texteditor has been scrolled, Eddie updates the line numbers in the margin. We can check for the number of lines in the texteditor when the timer fires. The command to retrieve the number of lines in a texteditor is !LINES and the syntax is as follows:

    #win.texteditor "!lines linecount"

After the command is given, the number of lines is contained in the numeric variable. You can give the variable any name you want. In Eddie, we use the variable name "rowcount" and the code looks like this:

    #1.te "!lines rowcount"

If the number of lines has changed, the user might have added or removed a branchlabel, so we refill the combobox. We only need to do this if the number of lines has changed, so we'll keep the number of lines in a variable called "lastRowcount", and test if the new number of lines is different than the previous number.

    if rowcount<>lastRowcount then gosub [fillBranch]

We then fill the "lastRowcount" variable with the new rowcount, ready for the next time it is tested.

    lastRowcount=rowcount

Here's the routine that's executed when the timer fires:

    'check the number of lines of text
    #1.te "!lines rowcount"
    'if it has changed, refill branch label combobox
    if rowcount<>lastRowcount then gosub [fillBranch]
    'new lastRowcount is this rowcount
    lastRowcount=rowcount

Getting Branchlabels for the Combobox

The sub "fillBranch" reads each line of code in the texteditor to see if it is a branchlabel, sub definition, or function definition. If it is, the line is added to the combobox array, and the combobox is updated.

Extracting Branchlabels from Code

Liberty BASIC can retrieve the text in a specified line in a texteditor control with the !LINE command. The syntax is as follows, from the helpfile.

print #handle, "!line n string$" ;

Returns the text at line n. In the code above, n is standing in for a literal number. If n is less than 1 or greater than the number of lines the text window contains, then "" (an empty string) is returned. After this command is issued, the line's text is contained in the variable string$.

This sample code retrieves the contents of line number 7 and places them into a variable called string$:

print #textwindow, "!line 7 string$"

The example in the helpfile puts the literal number 7 inside the quotation marks in the command. To use a variable instead, it looks like this:

    var=7
    print #textwindow, "!line ";var;" string$" 

We need to use a variable, because we'll read each line in turn, in a FOR...NEXT loop. We've retrieved the number of lines in the texteditor and placed that value into the variable "rowcount." Now we can loop through the lines in the texteditor, starting at "1" and ending with "rowcount."

    For i=1 to rowcount
        #1.te,"!line ";i;" line$";
        'evaluation code goes here
    Next i

Each row of text is placed into the string variable called "line$" and then it is evaluated.

The Combobox Array

Comboboxes are filled with the contents of an array. The array in Eddie is called "branch$()". Each time we want to refil the array with the list of branches, we use the REDIM command to make sure that the array is large enough to contain all of the branch labels. Of course, it isn't likely that each line of code is a branch label, but this insures that we won't get an "index out of bounds" error if the array is too small. REDIM changes the size of the array, and it removes all of the contents.

    REDIM branch$(rowcount)
    branch$(1)="<start>"

You can see that we've filled the first array element with a tag called "<start>". If the user selects this item from the combobox, we'll scroll the texteditor back to the top. This is a simple courtesy to our users, and it isn't mandatory. It's always nice to make things as user-friendly as possible, though!

Evaluating Lines -- Are They Branchlabels?

If we don't consider line numbers as labels, there are three ways ways that Liberty BASIC recognizes labels for code blocks. We won't even think about line numbers, since that system of labeling code is denigrated. The first way is the branch label. It begins with a square bracket, includes a single word description, and ends with a closing square bracket. Here's an example:

[openFile]

The branchlabel may be preceded by blank spaces. We can test for a branch label by looking for the opening square bracket, after trimming the blank spaces from the line of text with TRIM$() . Here's an example of TRIM$() :

var$ = "        Hello, World!        "
print trim$(var$)
'produces
Hello, World!
'not 
        Hello, World!

We then use the LEFT$() function to return only the first character from the line of text. LEFT$() returns the number of characters specified by "n" from the left side of a string of text. The syntax:

var$ = left$(string$,n)

Here's an example:

print left$("Liberty BASIC",3)
'produces
Lib

We've combined the two functions in a single expression in Eddie. It works like this:

print left$(trim$("       Liberty BASIC",3))
'produces
Lib

The function that is nested furthest into the expression is evaluated first. In this case, it is the "trim$()" function. The string of text is first trimmed of any leading or trailing blank spaces before the "left$()" function extracts the three characters on the left of the string of text.

If the first character that is not a blank space is an opening square bracket, we know the line contains a branch label.

            If Left$(Trim$(line$),1)="[" Then
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If

If the line contains a branch label, we add it to the array for the combobox, and increment a special counter called "bx" so that each new branch label is added to the next index in the array.

The second way that Liberty BASIC designates a code block is with a FUNCTION definition. This time, we use the WORD$() function to evaluate the line of text. Here is the syntax for the function. It retrieves the nth word in a string of text, breaking the text into chunks at the blank spaces. It does not return any blank spaces.

var$ = word$(string$,n)

In action, it looks like this:

print word$("Liberty BASIC",2)
'produces
BASIC

Since we have no way of knowing if the user has typed his function definition in lowercase, uppercase or mixed case, we'll convert the line to all lowercase for the comparison. We do this with the LOWER$() function. The syntax for lower is:

var$ = lower$("Liberty BASIC")

Printing var$ produces:

liberty basic

If the first word$ in the string is "function", we know it is a branchlabel and we add it to the combobox array and increment "bx". We trim the string to remove any leading or trailing blank spaces before loading it into the array.

            If Lower$(Word$(line$,1))="function" Then  
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If

The third king of code block begins with the word "sub." We look for that in the same way that we looked for "function." Here's the code from Eddie:

            If Lower$(Word$(line$,1))="sub" Then  
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If

Updating the Combobox

Once the array has been filled, all we need to do is update the combobox with a RELOAD command, like this:

    #1.c "reload"
    #1.c "selectindex 1";

Here's the entire code routine that reads each line of text, evaluates it, places branchlabels into the array and updates the combobox.

[fillBranch]
    timer 0
    #1.te "!lines rowcount"
    #1.te "!origin? col row"

    REDIM branch$(rowcount)
    branch$(1)="<start>"

    bx=2
    For i=1 to rowcount
        #1.te,"!line ";i;" line$";
            If Left$(Trim$(line$),1)="[" Then
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If
            If Lower$(Word$(line$,1))="function" Then  
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If
            If Lower$(Word$(line$,1))="sub" Then  
                branch$(bx)=Trim$(line$)
                bx=bx+1
            End If
    Next i

    #1.c "reload"
    #1.c "selectindex 1";
    TIMER 50, [activateTimer]
    return            

Responding to Combobox Events

To see how Eddie responds when the user selects an item in the combobox, read Scrolling the Texteditor

DEMO

For the Eddie code, go here: Eddie


Home

LB Wire Frame Lib

Stylebits - Listboxes

IExpress

Prompt

Icons

Screen Capture

Eddie's Lessons

Combobox

Scrolling Texteditor

Nested If/Then

Sprite Byte

Eddie

Moving Listbox Items

Newsletter help

Submissions

Index